package com.Coherence.Contrib.POF;

import java.io.IOException;

import com.tangosol.io.pof.PofReader;
import com.tangosol.io.pof.PofSerializer;
import com.tangosol.io.pof.PofWriter;
import com.tangosol.run.xml.XmlConfigurable;
import com.tangosol.run.xml.XmlElement;
import com.tangosol.util.Base;

public class POFGenericSerializer extends Base implements PofSerializer, XmlConfigurable {

	private int TypeId;
	private XmlElement config;
	private boolean LoadMetadata;

	public POFGenericSerializer(int TypeId) {
			this.TypeId = TypeId;
			Base.log(String.format("typeId initialized %d", TypeId));
	}
	
	public POFGenericSerializer(int TypeId, Boolean LoadMetadata) {
		this(TypeId);
		this.LoadMetadata=LoadMetadata;
}

	@Override
	public Object deserialize(PofReader reader) throws IOException {
		POFGenericObject obj;
		if (!LoadMetadata)
		{
			obj = new POFGenericObject();
			obj.objectData = reader.readBinary(0);
			return obj;
		}
		
		String[] MetaData = 
			loadMetaData(reader);

		Object[] properties = new Object[MetaData.length];
		for(int i = 1; i<= properties.length; i++)
		{
			properties[i-1] = reader.readObject(i);
		}

		return new POFGenericObject(properties, MetaData);
	}

	@Override
	public void serialize(PofWriter writer, Object obj) throws IOException {
		POFGenericObject object = (POFGenericObject) obj;
		if (!LoadMetadata)
		{
			writer.writeRemainder(object.objectData);
			return;
		}
		writer.writeObjectArray(0, object.metaData);
		Object[] properties = object.getProperties();
		for(int i = 1; i<= object.properties.length; i++)
		{
			writer.writeObject(i, properties[i-1]);
		}
	}

	private String[] loadMetaData(PofReader reader) throws IOException {
		Object[] objMetaData  = (reader.readObjectArray(0, null));
		if (objMetaData == null)
			throw new java.lang.NoClassDefFoundError("Metadata not found for type " + TypeId);
		String[] metaData = new String[objMetaData.length];
		for(int i=0; i<objMetaData.length;i++)
		{
			metaData[i] = (String) (objMetaData[i]);
		}
		return metaData;
	}

	@Override
	public XmlElement getConfig() {
		return config;
	}

	@Override
	public void setConfig(XmlElement config) {
		this.config = config;
		LoadMetadata = config.getSafeElement("LoadMetadata").getBoolean(false);
	}
}
